#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "sqldatabase.h"

#include <QContextMenuEvent>
#include <QInputDialog>
#include <QMessageBox>
#include <QSqlDatabase>
#include <QSqlQuery>


#include "comboboxdelegate.h"

#include "common.h"
#include "mydatedelegate.h"
#include "noeditdelegate.h"
#include "readonlydelegate.h"

#include "databasemanager.h"
#include "paginationcontroller.h"
#include "authcontroller.h"



MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::mainwindow)
{
    ui->setupUi(this);

    this->resize(QSize(1000, 800));

    //创建状态栏
    m_statusBar = ui->statusbar;
    m_statusBar->setObjectName("状态栏");


    initSqlModel();

    setupConnections();

    init();

    // 刷新
    ui->rbtn_queryModel->setChecked(true);  // 设置查询模式
    on_rbtn_queryModel_clicked();   // 默认查询模式

    // 连接卡号
    connect(ui->widget_sysSetWidget, &SysSetWidget::rxCard, [this](const QString &card){
        // 检查卡号是否存在

        // 检查时间是否异常

        // 检查
        if(m_dbManager->clockInOut(card)) {
            qDebug() << "打卡成功!";
        }

    });



    /*实现时间显示*/
    QLCDNumber *pTimeLcd = ui->lcdNumber;
    pTimeLcd->setDigitCount(19); //设置位数
    pTimeLcd->setMode(QLCDNumber::Dec); //十进制显示
    pTimeLcd->move(1200,20);
    pTimeLcd->resize(400,40); //设置大小  字体大小会按自动调整
    pTimeLcd->setSegmentStyle(QLCDNumber::Flat); //有三种风格  如上
    pTimeLcd->setStyleSheet("background:transparent;color:#000000;"); //背景透明 设置字体色


    // 考勤打卡
    connect(ui->cBox_department, &QComboBox::currentTextChanged, this, &MainWindow::do_updateDepartmentAtteView);
    connect(m_dbManager, &DatabaseManager::employeeCard, this, &MainWindow::do_add_empInfo);

    ui->groupBox_empCard->hide();   // 隐藏页面添加员工信息页


    //================ 动态UI配置 ================//
    QTableView *tableView = ui->tableView_deptAttendance;
    // 列宽设置（可随窗口大小调整）
    tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);


    // 样式配置（可动态修改）
    tableView->setAlternatingRowColors(true); // 交替颜色起用

    // 表头样式
    tableView->verticalHeader()->setDefaultSectionSize(70);
    tableView->horizontalHeader()->setMinimumHeight(50);
    tableView->horizontalHeader()->setStyleSheet("font-size:16pt;");

    // 设置选择模式和行为
    tableView->setSelectionMode(QAbstractItemView::ExtendedSelection);  // 多选  QAbstractItemView::ContiguousSelection
    tableView->setSelectionBehavior(QAbstractItemView::SelectRows);  // 选中整行
    tableView->setEditTriggers(QAbstractItemView::DoubleClicked);// | QAbstractItemView::SelectedClicked

    // 刷新界面
    on_actBtn_inputInfo_triggered();


    /** 考勤统计 */
    connect(ui->widget_statisticalWidget, &StatisticalWidget::queryStatistical, m_dbManager, &DatabaseManager::getAttendanceStatistics);
    connect(m_dbManager, &DatabaseManager::statisticsQuery, ui->widget_statisticalWidget, &StatisticalWidget::do_updateStatiscalView);
    connect(m_dbManager, &DatabaseManager::deptAttendance, ui->widget_statisticalWidget, &StatisticalWidget::do_updateStatiscalChart);
}

MainWindow::~MainWindow()
{
    delete ui;
}

// 初始化
void MainWindow::init()
{
    do_cBox_tables_updateTables();  // 更新查询页面，数据表下拉框

    // 分页显示
    ui->widget_page->setEnabled(true);

    // 是否获取到所有数据表
    bool isEnabled = !(ui->cBox_tables->currentText().isEmpty());
    ui->gBox_tables->setEnabled(isEnabled);
    ui->btn_refresh->setEnabled(isEnabled);

    ui->cBox_tables->setCurrentText(DatabaseManager::TABLE_NAMES.key(INI_TABLE)); // 设置初始化显示表格

    ui->gBox_operation->setEnabled(isEnabled);
    ui->btn_add->setEnabled(isEnabled);
    ui->btn_insert->setEnabled(isEnabled);
    ui->btn_submit->setEnabled(isEnabled);
    ui->btn_cancel->setEnabled(isEnabled);

    // 创建一个定时器
    m_timer = new QTimer(this);

    // 连接定时器的 timeout 信号到自定义的槽函数或信号
    connect(m_timer, &QTimer::timeout, this, &MainWindow::onTimeout);


    QTimer::singleShot(1000, [=](){
        // 设置定时器间隔为 500 毫秒
        m_timer->start(500); // 以毫秒为单位
    });
}

void MainWindow::onTimeout()
{
    // 刷新查询数据表
//    on_btn_refresh_clicked();
    bool isDirty = m_dbManager->getTableModel()->isDirty();
    ui->btn_cancel->setEnabled(isDirty);
    ui->btn_submit->setEnabled(isDirty);



    // 刷新考勤数据表

    //一秒刷新一下日期时间和考勤视图表
    static int lcdNumberCount = 0;
    // 切换到页面0，就刷新
    if(ui->stackedWidget->currentIndex() == 0) {
        lcdNumberCount = (lcdNumberCount + 1) % 2;
        if(!lcdNumberCount) {
            ui->lcdNumber->display(QDateTime::currentDateTime().toString("yyyy MM dd HH:mm:ss"));//刷新时间显示
            do_updateDepartmentAtteView(ui->cBox_department->currentText()); // 刷新考勤表
        }
    }

}

// 初始化查询模型
void MainWindow::initSqlModel()
{
    m_attendanceQueryModel = new QSqlQueryModel(this);
    m_dbManager = new DatabaseManager(ui->tableView, this);

    // 初始化页数控制
    m_pagination = new PaginationController(m_dbManager, this);

    m_dbManager->setPagination(m_pagination);

    // 页数显示标签
    connect(m_pagination, &PaginationController::paginationUpdated, [this](int current, int total){

        ui->spinBox_page->setValue(current);    // 设置当前显示页数
        updatePaginationButtons(current, total);    // 设置按键变化
    });
    // Qt提供的QOverload模板参数推导工具消除歧义
    connect(ui->spinBox_page,
            QOverload<int>::of(&QSpinBox::valueChanged),
            m_pagination,
            &PaginationController::gotoPage);

    // 映射模型
    // 映射初始化
    m_dataMapper = new QDataWidgetMapper(this);
    QSqlTableModel *tableModel = m_dbManager->getTableModel();
    if(!tableModel)
    {
        qDebug() << "初始化失败" << tableModel;
    }

    m_dataMapper->setModel(tableModel);
    m_dataMapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);

    // 绑定映射
    m_dataMapper->addMapping(ui->ledit_id, 0);
    m_dataMapper->addMapping(ui->ledit_fName, 1);
    // 根据表分支


}


#if 1
// 初始化连接
void MainWindow::setupConnections()
{
    // 控制器间通信
    connect(m_dbManager, &DatabaseManager::tableRefreshed, [=](){
        ui->tableView->setModel(m_dbManager->getTableModel());    //////// bug ////////
    });

    connect(m_dbManager, &DatabaseManager::dataOperationError, [this](const QString &error){
        m_statusBar->showMessage(error ,3000);// 状态栏显示错误信息
    });

    connect(m_dbManager, &DatabaseManager::dirty, [this](bool isDirty){
        ui->btn_submit->setEnabled(isDirty);
        ui->btn_cancel->setEnabled(isDirty);
    });

    connect(m_dbManager, &DatabaseManager::isSeletRow, [this](bool isSelet){
        ui->btn_add->setEnabled(isSelet);
        ui->btn_insert->setEnabled(isSelet);
        qDebug() << "接收到 isSeletRow 信号.";
    });

    connect(m_dbManager, &DatabaseManager::currentChanged, this, &MainWindow::do_currentChanged);

    connect(ui->btn_add, &QPushButton::clicked, m_dbManager, &DatabaseManager::onAdd);
    connect(ui->btn_insert, &QPushButton::clicked, m_dbManager, &DatabaseManager::onInsert);
    connect(ui->btn_submit, &QPushButton::clicked, m_dbManager, &DatabaseManager::onSubmit);
    connect(ui->btn_cancel, &QPushButton::clicked, m_dbManager, &DatabaseManager::onCancel);
    connect(ui->btn_delete, &QPushButton::clicked, m_dbManager, &DatabaseManager::onDelete);

    connect(ui->btn_next_page, &QPushButton::clicked, m_pagination, &PaginationController::nextPage);
    connect(ui->btn_prev_page, &QPushButton::clicked, m_pagination, &PaginationController::prevPage);
    connect(ui->btn_first_page, &QPushButton::clicked, m_pagination, &PaginationController::firstPage);
    connect(ui->btn_last_page, &QPushButton::clicked, m_pagination, &PaginationController::lastPage);

//     connect(m_pagination, &PaginationController::pageChanged, [this](int page){
//          qDebug() << "接收到 m_pagination 的信号 pageChanged:" << page;
// //        QString tabName = ui->cBox_tables->currentText();
// //        m_dbManager->refreshTable(DatabaseManager::TABLE_NAMES.value(tabName), page);           //////// bug ////////
//     });



    // UI事件
    connect(ui->cBox_tables, &QComboBox::currentTextChanged,
            this, &MainWindow::onTableSelectionChanged);
}

void MainWindow::initUI()
{

}

// 处理表格切换
void MainWindow::onTableSelectionChanged(const QString& tableName)
{
    Q_UNUSED(tableName);
//    m_pagination->firstPage();
//    int total = m_dbManager->getTotalRecords(tableName);// 获取当前表格记录总数
//    m_pagination->setupPagination(total);   // 设置当前页数
//    m_dbManager->refreshTable(DatabaseManager::TABLE_NAMES.value(tableName));   // 刷新
}

void MainWindow::onRefreshClicked()
{

}

void MainWindow::showContextMenu(const QPoint &pos)
{
    Q_UNUSED(pos);
}
#endif






// 右键菜单处理
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    // 创建右键菜单
    QMenu contextMenu(this);

    // 添加“更新”和“删除”选项
//    QAction* updateAction = new QAction(tr("更新"), this);
    QAction* deleteAction = new QAction(tr("删除"), this);

    // 将选项添加到菜单
//    contextMenu.addAction(updateAction);
    contextMenu.addAction(deleteAction);

    // 连接操作
//    connect(updateAction, &QAction::triggered, m_dbManager, &DatabaseManager::updateSelectedRows);
    connect(deleteAction, &QAction::triggered, m_dbManager, &DatabaseManager::onDelete);

    // 显示菜单
    contextMenu.exec(event->globalPos());
}


// 表格下拉框
void MainWindow::do_cBox_tables_currentTextChange(const QString &text)
{
    // 加载数据表
    if(m_authority) {
        QString currentTable = text;
        // 更新表格
        if(m_alterFlag) {
            // 修改模式
            m_dbManager->refreshTable(DatabaseManager::TABLE_NAMES.value(currentTable));
        } else {
            m_dbManager->m_currentTable = DatabaseManager::TABLE_NAMES.value(currentTable);
            int page = m_pagination->currentPage();
            m_pagination->gotoPage(page);
        }

    } else {
        m_pagination->firstPage();
    }
}

void MainWindow::do_cBox_tables_updateTables()
{
    QString currentTable = ui->cBox_tables->currentText();
    disconnect(ui->cBox_tables, &QComboBox::currentTextChanged, this, &MainWindow::do_cBox_tables_currentTextChange);
    QStringList tables(m_dbManager->getTables());// 获取所有所有表名

    // 过滤系统数据表
    for(QString &table : tables) {
        if(false == DatabaseManager::TABLE_HEADERS.contains(table)) {
            tables.removeAll(table);
        }
    }

    QStringList tablesAs;
    for(const QString &table : tables) {
        tablesAs << DatabaseManager::TABLE_NAMES.key(table);
    }

    ui->cBox_tables->clear();
    ui->cBox_tables->addItems(tablesAs);  // 添加到下拉框
    connect(ui->cBox_tables, &QComboBox::currentTextChanged, this, &MainWindow::do_cBox_tables_currentTextChange);

    ui->cBox_tables->setCurrentText(currentTable);// 设置到当前
}

void MainWindow::do_add_empInfo(const QString &rfidCard)
{
    ui->groupBox_empCard->show();
    on_actBtn_inputInfo_triggered();    // 跳转到考勤页面
    ui->ledit_id->setText(rfidCard);    // 设置卡号
}


// 选择模型
void MainWindow::do_currentChanged(QModelIndex current, QModelIndex perivous)
{
    qDebug() << " do_currentChanged 进来了";
    Q_UNUSED(current);
    Q_UNUSED(perivous);

    const bool &isEnabled = m_dbManager->getTableModel()->isDirty();

    ui->btn_submit->setEnabled(isEnabled);
    ui->btn_cancel->setEnabled(isEnabled);
}


// 数据库操作
void MainWindow::on_btn_refresh_clicked()
{
    // 更新下拉框
    do_cBox_tables_updateTables();

    QString currentTable = ui->cBox_tables->currentText(); // 获取当前表名
    qDebug() << "刷新 " << currentTable << "表 数据.";
    m_dbManager->m_currentTable = DatabaseManager::TABLE_NAMES.value(currentTable);
    // 更新表格
    if(m_alterFlag) {
        // 修改模式
        m_dbManager->refreshTable(DatabaseManager::TABLE_NAMES.value(currentTable));
    } else {

        int page = m_pagination->currentPage();
        m_pagination->gotoPage(page);
    }
}

void MainWindow::on_spinBox_page_valueChanged(int value)
{
//    m_pagination->setCurrentPage(value);
    qDebug() << "on_spinBox_page_valueChanged:" << value;
    int total = m_pagination->totalPages();
    if(value > total) {
        value = total;
        ui->spinBox_page->setValue(value);
    } else {
        m_pagination->setCurrentPage(value);
    }

}


// 假设 totalPages 是获取到的总页数
void MainWindow::updatePaginationButtons(int currentPage, int totalPages)
{
    ui->le_pageNumber->setText(QString("%1 / %2 页数").arg(currentPage).arg(totalPages));

    ui->btn_prev_page->setEnabled(currentPage > 1);
    ui->btn_next_page->setEnabled(currentPage < totalPages);
    ui->btn_first_page->setEnabled(currentPage != 1);
    ui->btn_last_page->setEnabled(currentPage != totalPages);
    ui->spinBox_page->setEnabled(totalPages > 1);
}


// 带自动排序的去重（使用QSet）
void MainWindow::addSortedUniqueItems(QComboBox* comboBox, const QStringList& items)
{
    QSet<QString> uniqueSet(items.begin(), items.end()); // 使用迭代器构造 QSet 去重
    QStringList uniqueList(uniqueSet.begin(), uniqueSet.end()); // 直接通过迭代器构造 QStringList
    uniqueList.sort(Qt::CaseInsensitive); // 按字母不区分大小写排序
    comboBox->clear();
    comboBox->addItems(uniqueList);
}

void MainWindow::do_updateDepartmentAtteView(const QString &deptName)
{

    QString dept = deptName;
    // 查询
    // 表是否存在
    if (!DatabaseManager::departmentExists(deptName)) {
        // qDebug() << "表:" << deptName << " 不存在";
        dept = QString();
    }

    // 考勤数据
    QSqlQuery query = m_dbManager->getAttendanceData(QDate::currentDate(), dept);

    // 显示数据
    QSqlQueryModel *model = m_attendanceQueryModel;
    model->setQuery(query);
    ui->tableView_deptAttendance->setModel(model);
}


// 界面切换
void MainWindow::on_actBtn_inputInfo_triggered()
{
    qDebug() << "添加员工信息页面";
    ui->stackedWidget->setCurrentIndex(0);

    // 更新部门表下拉框
    QStringList departments(m_dbManager->getDepartments());
    addSortedUniqueItems(ui->cBox_department, departments); // 刷新视图页下拉框
    addSortedUniqueItems(ui->cBox_deptName, departments);   // 刷新添加员工页下拉框
    ui->cBox_department->addItem("所有部门");
    ui->cBox_department->setCurrentText("所有部门");
}

void MainWindow::on_actBtn_queryInfo_triggered()
{
    qDebug() << "数据库信息查询页面";
    ui->stackedWidget->setCurrentIndex(1);
}

void MainWindow::on_actBtn_statistical_triggered()
{
    qDebug() << "考勤统计页面";
    ui->stackedWidget->setCurrentIndex(2);

    // 更新部门下拉框
    QStringList departments(m_dbManager->getDepartments());
    ui->widget_statisticalWidget->do_updateDeptCoboxCom(departments);

    ui->widget_statisticalWidget->on_btn_update_clicked();
}

void MainWindow::on_actBtn_setAttendanceTime_triggered()
{
    qDebug() << "考勤时间设置页面";
    ui->stackedWidget->setCurrentIndex(3);

    ui->widget_setAtteTimeWidget->loadSettings();
}

void MainWindow::on_actBtn_deviceConnect_triggered()
{
    qDebug() << "设备连接页面";
    ui->stackedWidget->setCurrentIndex(4);
}

void MainWindow::on_rbtn_queryModel_clicked()
{
    // 查询模式配置
    m_alterFlag = false;
    ui->gBox_operation->hide();
    ui->widget_page->show();

    on_btn_refresh_clicked();   // 刷新
}

void MainWindow::on_rbtn_alterModel_clicked()
{
    // 可修改模式配置
    m_alterFlag = true;
    ui->gBox_operation->show();
    ui->widget_page->hide();

    on_btn_refresh_clicked();   // 刷新
}

// 添加新员工，并考勤打卡
void MainWindow::on_btn_ok_clicked()
{
    // 检查用户输入
    // 卡号
    QString rfidCard = ui->ledit_id->text().trimmed();
    if(rfidCard.isEmpty()) {
        m_statusBar->showMessage("卡号不能为空", 3000);
        return;
    }
    // 员工姓名
    QString fName = ui->ledit_fName->text().trimmed();
    if(fName.isEmpty()) {
        m_statusBar->showMessage("员工姓不能为空", 3000);
        return;
    }

    QString gName = ui->ledit_gName->text().trimmed();
    if(gName.isEmpty()) {
        m_statusBar->showMessage("员工名不能为空", 3000);
        return;
    }
    QString empName = fName + " " + gName;  // 拼接


    // 职位
    QString position = ui->cBox_position->currentText();

    // 部门
    QString deptName = ui->cBox_deptName->currentText();
    if(deptName.isEmpty()) {
        m_statusBar->showMessage("部门名称不能为空", 3000);
        return;
    }

    // 查询部门是否存在
    if(!m_dbManager->departmentExists(deptName)) {
        m_statusBar->showMessage("部门名不存在", 3000);
        return;
    }

    // 添加新员工
    int empId = m_dbManager->registerEmployee(rfidCard, empName, deptName, position);
    if(empId < 0) {
        m_statusBar->showMessage("添加失败", 3000);
        return;
    }

    // 隐藏
    on_btn_conceal_clicked();
}


// 取消添加，并隐藏
void MainWindow::on_btn_conceal_clicked()
{
    // 清空输入框
    ui->ledit_id->clear();
    ui->ledit_fName->clear();
    ui->ledit_gName->clear();
    ui->cBox_deptName->clear();
    ui->cBox_position->setCurrentIndex(0);

    // 隐藏
    ui->groupBox_empCard->hide();
}

